/*
 * File:   PWM.c
 * Author: Saimon
 *
 * Created on March 16, 2019, 3:22 PM
 */

//#include	<math.h>
#include "i2c_register.h"
#include "mcc_generated_files/mcc.h"
#include "PWM.h"
#include "main.h"
#include "GPports.h"
#include "DataVariable.h"


const uint16_t gamma_table[7][100] = {
    { 1012, 1002, 991, 981, 971, 961, 950, 940, 930, 920, 910, 899, 889, 879, 869, 858, 848, 838, 828, 818, 807, 797, 787, 777, 766, 756, 746, 736, 726, 715, 705, 695, 685, 675, 664, 654, 644, 634, 623, 613, 603, 593, 583, 572, 562, 552, 542, 531, 521, 511, 501, 491, 480, 470, 460, 450, 439, 429, 419, 409, 399, 388, 378, 368, 358, 347, 337, 327, 317, 307, 296, 286, 276, 266, 255, 245, 235, 225, 215, 204, 194, 184, 174, 164, 153, 143, 133, 123, 112, 102, 92, 82, 72, 61, 51, 41, 31, 20, 10, 0}, //Linear
    { 1022, 1021, 1020, 1019, 1017, 1016, 1013, 1011, 1009, 1006, 1003, 1000, 996, 992, 988, 984, 980, 975, 971, 966, 960, 955, 949, 944, 938, 932, 925, 919, 912, 905, 898, 891, 883, 875, 868, 860, 851, 843, 834, 826, 817, 808, 798, 789, 779, 769, 759, 749, 739, 729, 718, 707, 696, 685, 674, 662, 650, 639, 627, 615, 602, 590, 577, 564, 551, 538, 525, 512, 498, 484, 470, 456, 442, 428, 413, 398, 384, 369, 353, 338, 323, 307, 291, 275, 259, 243, 227, 210, 193, 177, 160, 142, 125, 108, 90, 72, 55, 36, 18, 0}, //GAMMA 1.8
    { 1022, 1022, 1021, 1020, 1019, 1018, 1017, 1015, 1014, 1012, 1010, 1007, 1005, 1002, 999, 996, 992, 989, 985, 981, 977, 973, 968, 963, 958, 953, 947, 942, 936, 930, 924, 917, 911, 904, 897, 890, 882, 874, 867, 858, 850, 842, 833, 824, 815, 806, 796, 787, 777, 766, 756, 746, 735, 724, 713, 702, 690, 678, 666, 654, 642, 629, 616, 603, 590, 577, 563, 549, 535, 521, 507, 492, 477, 462, 447, 432, 416, 400, 384, 368, 351, 335, 318, 301, 284, 266, 248, 231, 212, 194, 176, 157, 138, 119, 100, 80, 60, 40, 20, 0}, //GAMMA 2.0
    { 1022, 1022, 1022, 1021, 1021, 1020, 1019, 1018, 1017, 1016, 1014, 1012, 1011, 1008, 1006, 1004, 1001, 999, 996, 992, 989, 985, 982, 978, 974, 969, 965, 960, 955, 950, 944, 939, 933, 927, 921, 914, 907, 900, 893, 886, 878, 870, 862, 854, 846, 837, 828, 819, 809, 800, 790, 780, 769, 759, 748, 737, 725, 714, 702, 690, 678, 665, 652, 639, 626, 612, 599, 585, 570, 556, 541, 526, 511, 495, 479, 463, 447, 430, 414, 396, 379, 362, 344, 326, 307, 289, 270, 251, 231, 211, 191, 171, 151, 130, 109, 88, 66, 44, 22, 0}, //GAMMA 2.09 0}, //GAMMA 2.2
    { 1022, 1022, 1022, 1022, 1021, 1021, 1020, 1020, 1019, 1018, 1017, 1016, 1014, 1013, 1011, 1009, 1007, 1005, 1003, 1001, 998, 995, 992, 989, 985, 982, 978, 974, 970, 965, 961, 956, 951, 945, 940, 934, 928, 922, 915, 909, 902, 895, 887, 880, 872, 863, 855, 846, 838, 828, 819, 809, 799, 789, 779, 768, 757, 746, 734, 722, 710, 698, 685, 672, 659, 645, 631, 617, 603, 588, 573, 557, 542, 526, 510, 493, 476, 459, 442, 424, 406, 387, 369, 349, 330, 310, 290, 270, 249, 228, 207, 185, 163, 141, 118, 95, 72, 48, 24, 0}, //GAMMA 2.4
    { 1022, 1022, 1022, 1022, 1022, 1021, 1021, 1021, 1020, 1019, 1019, 1018, 1017, 1016, 1015, 1013, 1012, 1010, 1008, 1006, 1004, 1002, 1000, 997, 994, 991, 988, 985, 981, 977, 973, 969, 965, 960, 955, 950, 945, 939, 934, 928, 921, 915, 908, 901, 894, 886, 878, 870, 862, 853, 845, 835, 826, 816, 806, 796, 785, 774, 763, 751, 739, 727, 715, 702, 689, 675, 661, 647, 633, 618, 603, 587, 571, 555, 538, 521, 504, 486, 468, 450, 431, 412, 392, 373, 352, 332, 310, 289, 267, 245, 222, 199, 176, 152, 128, 103, 78, 52, 26, 0}, //GAMMA 2.6
    { 1022, 1022, 1022, 1022, 1022, 1022, 1021, 1021, 1021, 1020, 1020, 1019, 1019, 1018, 1017, 1016, 1015, 1014, 1012, 1011, 1009, 1007, 1005, 1003, 1001, 998, 996, 993, 990, 987, 984, 980, 976, 972, 968, 964, 959, 954, 949, 943, 938, 932, 926, 919, 913, 906, 899, 891, 883, 875, 867, 858, 849, 840, 830, 820, 810, 800, 789, 778, 766, 754, 742, 729, 716, 703, 689, 675, 660, 646, 630, 615, 599, 582, 565, 548, 530, 512, 494, 475, 455, 436, 415, 395, 374, 352, 330, 307, 285, 261, 237, 213, 188, 163, 137, 110, 84, 56, 28, 0}, //GAMMA 2.8
};

/*
 * @brief Update the PWM value of the GP1
 */
void PWM_GP1(uint8_t duty) {

    if (duty == 0) {

        GP1_SetHigh();
        UNLOCK_PPS;
        RC7PPSbits.RC7PPS = 0x00;
        LOCK_PPS;
        PWM5CON = 0;
        return;
    }

    if (PWM5CON == 0) {
        UNLOCK_PPS;
        RC7PPSbits.RC7PPS = 0x02; //RC7->PWM5:PWM5; 
        LOCK_PPS;
        PWM5CON = 0x80;
    }

    if (GAMMAGP1 == 0) {
        PWM5DCH = 0xFFU - duty;
        PWM5DCL = 0;
    } else {
        if (duty > 100)
            duty = 100;
        PWM5DCH = (gamma_table[GAMMAGP1 - 1U][(duty - 1U)] & 0x03FC) >> 2U;
        PWM5DCL = (gamma_table[GAMMAGP1 - 1U][(duty - 1U)] & 0x0003) << 6U;
    }

}

/*
 * @brief Update the PWM value of the GP2
 */
void PWM_GP2(uint8_t duty) {

    if (duty == 0) {

        GP2_SetHigh();
        UNLOCK_PPS;
        RC6PPSbits.RC6PPS = 0x00;
        LOCK_PPS;
        CCP4CON = 0;
        return;
    }
    if (CCP4CON == 0) {
        UNLOCK_PPS;
        RC6PPSbits.RC6PPS = 0x0F; //RC6->CCP4:CCP4;
        LOCK_PPS;
        CCP4CON = 0x8F;
    }
    if (GAMMAGP2 == 0) {

        CCPR4 = (uint16_t) (0xff - duty) << 2;

    } else {
        if (duty > 100)
            duty = 100;
        CCPR4 = (uint16_t) gamma_table[GAMMAGP2 - 1U][(duty - 1U)];
    }
}

/*
 * @brief Update the PWM value of the GP3
 */
void PWM_GP3_RLED(uint8_t duty) {

    if (duty == 0) {

        PWM_LR_GP3_SetHigh();
        UNLOCK_PPS;
        RC5PPSbits.RC5PPS = 0x00;
        LOCK_PPS;
        CCP1CON = 0;
        return;
    }

    if (CCP1CON == 0) {
        UNLOCK_PPS;
        RC5PPSbits.RC5PPS = 0x0C; //RC5->CCP1:CCP1;  
        LOCK_PPS;
        CCP1CON = 0x8F;
        CCPR1 = 0xFFFF;
    }

    if (GAMMAGP3_RLED == 0) {

        CCPR1 = (uint16_t) (0xff - duty) << 2;

    } else {
        if (duty > 100)
            duty = 100;

        CCPR1 = gamma_table[GAMMAGP3_RLED - 1U][(duty - 1U)];
    }
}

/*
 * @brief Update the PWM value of the Green color LED
 */
void PWM_GLED(uint8_t duty) {

    if (duty == 0) {

        PWM_LG_SW_SetHigh();
        UNLOCK_PPS;
        RC4PPSbits.RC4PPS = 0x00;
        LOCK_PPS;
        CCP2CON = 0;
        return;
    }

    if (CCP2CON == 0) {
        UNLOCK_PPS;
        RC4PPSbits.RC4PPS = 0x0D; //RC4->CCP2:CCP2;   
        LOCK_PPS;
        CCP2CON = 0x8F;
        CCPR2 = 0xFFFF;
    }

    if (GAMMAGLED == 0) {
        CCPR2 = (uint16_t) (0xff - duty) << 2;

    } else {

        if (duty > 100)
            duty = 100;

        CCPR2 = gamma_table[GAMMAGLED - 1U][(duty - 1U)];
    }
}

/*
 * @brief Update the PWM value of the Green color LED
 */
void PWM_BLED(uint8_t duty) {

    if (duty == 0) {

        PWM_LB_SWC_SetHigh();
        UNLOCK_PPS;
        RC3PPSbits.RC3PPS = 0x00;
        LOCK_PPS;
        CCP3CON = 0;
        return;
    }


    if (CCP3CON == 0) {
        UNLOCK_PPS;
        RC3PPSbits.RC3PPS = 0x0E; //RC3->CCP3:CCP3;  
        LOCK_PPS;
        CCP3CON = 0x8F;
        CCPR3 = 0xFFFF;
    }

    if (GAMMABLED == 0) {

        CCPR3 = (uint16_t) (0xff - duty) << 2;

    } else {

        if (duty > 100)
            duty = 100;

        CCPR3 = gamma_table[GAMMABLED - 1U][(duty - 1U)];
    }
}